<template>
  <el-card shadow="always" :body-style="{ padding: '20px' }">
    <template #header>
      <el-form label-width="80px" :inline="true">
        <el-form-item label="用户名:">
          <el-input placeholder="请输入" v-model="roleName"></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" icon="ele-Search" @click="search"
            >搜索</el-button
          >
          <el-button type="primary" icon="ele-Plus" @click="clickAdd"
            >新增</el-button
          >
        </el-form-item>
      </el-form>
    </template>
    <el-table :data="roleList" border stripe v-loading="loading">
      <el-table-column type="index" width="80" label="序号" />
      <el-table-column label="ID" prop="id" width="100"> </el-table-column>
      <el-table-column label="角色名" prop="roleName"> </el-table-column>
      <el-table-column label="创建时间" prop="createTime"> </el-table-column>
      <el-table-column label="更新时间" prop="updateTime"> </el-table-column>

      <el-table-column label="操作">
        <template v-slot="{ row }">
          <el-button type="success" size="default" @click="showRole(row.id)"
            >权限</el-button
          >
          <el-button type="primary" size="default" @click="edit(row)"
            >编辑</el-button
          >
          <el-button type="danger" size="default">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <el-pagination
      :style="{ marginTop: '20px' }"
      v-model:currentPage="currentPage"
      v-model:page-size="pageSize"
      layout="->,total, prev, pager, next, sizes ,jumper"
      :page-sizes="[20, 40, 80, 100]"
      :total="totalNum"
      background
      :pager-count="7"
    >
    </el-pagination>
  </el-card>

  <el-dialog
    :title="roleInfo.id ? '修改' : '新增'"
    v-model="showDialog"
    width="40%"
    top="60"
    :style="{ marginTop: '30px' }"
  >
    <el-form label-width="100px" :inline="false">
      <el-form-item label="角色名称:">
        <el-input placeholder="请输入" v-model="roleInfo.roleName"></el-input>
      </el-form-item>
    </el-form>
    <template #footer>
      <span>
        <el-button @click="showDialog = false">取消</el-button>
        <el-button type="primary" @click="addOrEditUser">确定</el-button>
      </span>
    </template>
  </el-dialog>

  <el-drawer v-model="showDrawer" title="权限配置">
    <el-button type="primary" size="default" @click="roleAddMenu"
      >确定</el-button
    >

    <el-tree
      ref="tree"
      :data="roleMenuList"
      :props="props"
      show-checkbox
      node-key="id"
      @check="handleCheckChange"
      :default-checked-keys="roleIdList"
    />
  </el-drawer>
</template>

<script lang="ts">
import {
  reqAddRoleInfo,
  reqGetMenu,
  reqGetRoleList,
  reqUpdateRoleInfo,
  reqRoleAddMenu,
} from "@/api/system/role";
import {
  RoleItemType,
  RoleListType,
  RoleMenuListType,
} from "@/api/system/role/types";
import { ElMessage } from "element-plus";
import { defineComponent } from "vue";

export default defineComponent({
  name: "Role",
});
</script>

<script setup lang="ts">
import { ref, onMounted, watch } from "vue";
const currentPage = ref(1);
const pageSize = ref(10);
const totalNum = ref(0);
const roleName = ref("");
const loading = ref(false);
const showDialog = ref(false);
const roleList = ref<RoleListType>([]);
const roleInfo = ref<RoleItemType>({
  id: null,
  roleName: "",
});

/**
 * 封装获取用户列表函数
 */
const getRoleList = async (page: number = currentPage.value) => {
  try {
    loading.value = true;
    const res = await reqGetRoleList(page, pageSize.value, roleName.value);
    roleList.value = res.records;
    totalNum.value = res.total;
    loading.value = false;
  } catch (error: any) {
    ElMessage.error("请求数据失败:" + error.message);
  }
};

/**
 * 组件初始化完毕时执行
 */
onMounted(() => {
  getRoleList();
});

/**
 * 监听页码和条数的变化执行
 */
watch([currentPage, pageSize], () => {
  getRoleList();
});

/**
 * 点击搜索时执行的函数
 */
const search = () => {
  getRoleList(1);
};

/**
 * 点击添加按钮
 */
const clickAdd = () => {
  showDialog.value = true;
  roleInfo.value = {
    id: null,
    roleName: "",
  };
};

/**
 * 点击编辑按钮
 */
const edit = (row: RoleItemType) => {
  showDialog.value = true;
  roleInfo.value = row;
};

/**
 * 点击确认按钮(添加或则修改)
 */

const addOrEditUser = async () => {
  if (roleInfo.value.id) {
    // 修改
    try {
      await reqUpdateRoleInfo(roleInfo.value);
      ElMessage.success("修改成功");
      showDialog.value = false;
      getRoleList();
    } catch (error: any) {
      ElMessage.error("修改失败:" + error.message);
    }
  } else {
    // 添加
    try {
      await reqAddRoleInfo(roleInfo.value);
      ElMessage.success("添加成功");
      showDialog.value = false;
      getRoleList();
    } catch (error: any) {
      ElMessage.error("添加失败:" + error.message);
    }
  }
};

/**
 * !!! 设置角色权限
 */

// 初始化数据
const showDrawer = ref(false);
const roleMenuList = ref<RoleMenuListType>([]);
const tree = ref();
const roleIdList = ref<number[]>([]);
const currentRoleId = ref(0);
const props = {
  label: "name",
  children: "children",
};

/**
 * 封装一个递归取出id的函数
 */
const extractIds = (data: any): number[] => {
  let ids = [];
  if (Array.isArray(data)) {
    for (let item of data) {
      if (item.select) {
        ids.push(item.id);
      }
      if (item.children) {
        ids = ids.concat(extractIds(item.children));
      }
    }
  } else if (typeof data === "object" && data !== null) {
    if (data.select) {
      ids.push(data.id);
    }
    for (let key in data) {
      if (data[key] instanceof Array || typeof data[key] === "object") {
        ids = ids.concat(extractIds(data[key]));
      }
    }
  }
  return ids;
};
/**
 * 点击权限按钮
 */
const showRole = async (id: number) => {
  roleIdList.value = [];
  currentRoleId.value = id;
  showDrawer.value = true;
  try {
    const res = await reqGetMenu(id);
    roleMenuList.value = res;
    roleIdList.value = extractIds(res);
    console.log(res);
  } catch (error: any) {
    ElMessage.error("获取权限信息失败:" + error.message);
  }
};

/**
 * 树形控件的选择触发事件
 */

const resIdlist = ref<number[]>([]);
const handleCheckChange = (_: any, SelectedObj: any) => {
  SelectedObj.halfCheckedKeys.shift();
  roleIdList.value = [...SelectedObj.checkedKeys];
  resIdlist.value = [
    ...SelectedObj.checkedKeys,
    ...SelectedObj.halfCheckedKeys,
  ];
};

/**
 * 确认添加权限
 */
const roleAddMenu = async () => {
  try {
    await reqRoleAddMenu(currentRoleId.value, resIdlist.value);
    ElMessage.success("设置权限成功");
    showDrawer.value = false;
  } catch (error: any) {
    ElMessage.error("设置权限成失败:" + error.message);
  }
};
</script>

<style scoped></style>
